﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Drawing;
using System.Web.UI;
using Top.Common;
using Top.Oss;

namespace Top.UpLoad
{
    public class UpLoadHelper
    {
        private string attachextension = "gif,jpg,png,bmp,rar,zip,doc,xls,txt,docx";//文件上传类型
        private int attachimgsize = 2048;//图片上传大小
        private int attachfilesize = 51200;//文件上传大小
        public static string webpath = "/";
        public static string attachpath = "UpLoad";
        //public static string thumbSize = "60_60,100_100,190_190,230_230,300_300,350_350,800_800";
        public UpLoadHelper() { }


        /// <summary>
        /// 文件上传方法A
        /// </summary>
        /// <param name="postedFile">文件流</param>
        /// <returns>服务器文件路径</returns>
        public string fileSaveAs(HttpPostedFile postedFile)
        {
            return fileSaveAs(postedFile, false, false);
        }

        /// <summary>
        /// 文件上传方法B
        /// </summary>
        /// <param name="postedFile">文件流</param>
        /// <param name="isImage">是否必须上传图片</param>
        /// <returns>服务器文件路径</returns>
        public string fileSaveAs(HttpPostedFile postedFile, bool _isImage)
        {
            return fileSaveAs(postedFile, _isImage, false);
        }

        /// <summary>
        /// 文件上传方法C
        /// </summary>
        /// <param name="postedFile">文件流</param>
        /// <param name="isReOriginal">是否返回文件原名称</param>
        /// <returns>服务器文件路径</returns>
        public string fileSaveAs(HttpPostedFile postedFile, bool _isImage, bool _isReOriginal)
        {
            try
            {
                string fileExt = Utils.GetFileExt(postedFile.FileName); //文件扩展名，不含“.”
                string originalFileName = postedFile.FileName.Substring(postedFile.FileName.LastIndexOf(@"\") + 1); //取得文件原名
                string fileName = Utils.GetRamCode() + "." + fileExt; //随机文件名
                //string[] sizeList = thumbSize.Split(',');
                //string dirPath = GetUpLoadPath(); //上传目录相对路径

                //检查文件扩展名是否合法
                if (!CheckFileExt(fileExt))
                {
                    return "{\"msg\": 0, \"msgbox\": \"不允许上传" + fileExt + "类型的文件！\"}";
                }
                //检查是否必须上传图片
                if (_isImage && !IsImage(fileExt))
                {
                    return "{\"msg\": 0, \"msgbox\": \"对不起，仅允许上传图片文件！\"}";
                }
                //检查文件大小是否合法
                if (!CheckFileSize(fileExt, postedFile.ContentLength))
                {
                    return "{\"msg\": 0, \"msgbox\": \"文件超过限制的大小啦！\"}";
                }
                //获得要保存的文件路径
                //string serverFileName = dirPath + fileName;
                //string returnFileName = serverFileName;

                ////物理完整路径                    
                //string toFileFullPath = Utils.GetMapPath(dirPath);
                ////检查有该路径是否就创建
                //if (!Directory.Exists(toFileFullPath))
                //{
                //    Directory.CreateDirectory(toFileFullPath);
                //}
                //保存文件
                //postedFile.SaveAs(toFileFullPath + fileName);
                string returnFileName = UpLoadToOSS(postedFile.FileName, postedFile.InputStream, fileExt);


                //foreach (var size in sizeList)
                //{
                //    string thumbDirPath = string.Format("{0}thum{1}/", toFileFullPath, size);
                //    if (!Directory.Exists(thumbDirPath))
                //        Directory.CreateDirectory(thumbDirPath);
                //    string[] widthAndHeight = size.Split('_');
                //    GenerateThumb(toFileFullPath + fileName, thumbDirPath + fileName,
                //        int.Parse(widthAndHeight[0]),
                //        int.Parse(widthAndHeight[1]), "HW");
                //}

                ////如果需要返回原文件名
                //if (_isReOriginal)
                //{
                //    return "{\"msg\": 1, \"msgbox\": \"" + serverFileName + "\", \"mstitle\": \"" + originalFileName + "\"}";
                //}
                return "{\"msg\": 1, \"msgbox\": \"" + returnFileName + "\"}";
            }
            catch
            {
                return "{\"msg\": 0, \"msgbox\": \"上传过程中发生意外错误！\"}";
            }
        }

        public static string UpLoadToOSS(string filePath, Stream stream, string fileExt)
        {
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmssf") + "-" + Rand.Number(5) + "." + fileExt;
            OssHelper.Upload("", fileName, stream);
            return TopConfigHelper.GetAppSettings("OssImgServer") + OssHelper.PreFolder + fileName + "@200";
        }


        public static void GenerateThumb(string imagePath, string thumbPath, int width, int height, string mode)
        {
            Image image = Image.FromFile(imagePath);

            string extension = imagePath.Substring(imagePath.LastIndexOf(".")).ToLower();
            ImageFormat imageFormat = null;
            switch (extension)
            {
                case ".jpg":
                case ".jpeg":
                    imageFormat = ImageFormat.Jpeg;
                    break;
                case ".bmp":
                    imageFormat = ImageFormat.Bmp;
                    break;
                case ".png":
                    imageFormat = ImageFormat.Png;
                    break;
                case ".gif":
                    imageFormat = ImageFormat.Gif;
                    break;
                default:
                    imageFormat = ImageFormat.Jpeg;
                    break;
            }

            int toWidth = width > 0 ? width : image.Width;
            int toHeight = height > 0 ? height : image.Height;

            int x = 0;
            int y = 0;
            int Ow = image.Width;
            int Oh = image.Height;

            switch (mode)
            {
                case "HW"://指定高宽缩放（可能变形）
                    break;
                case "W"://指定宽，高按比例
                    toHeight = image.Height * width / image.Width;
                    break;
                case "H"://指定高，宽按比例
                    toWidth = image.Width * height / image.Height;
                    break;
                case "Cut":
                    if ((double)image.Width / (double)image.Height > (double)toWidth / (double)toHeight)
                    {
                        Oh = image.Height;
                        Ow = image.Height * toWidth / toHeight;
                        y = 0;
                        x = (image.Width - Ow) / 2;
                    }
                    else
                    {
                        Ow = image.Width;
                        Oh = image.Width * height / toWidth;
                        x = 0;
                        y = (image.Height - Oh) / 2;
                    }
                    break;
                default:
                    break;

            }
            //新建一个bmp
            Image bitmap = new Bitmap(toWidth, toHeight);

            //新建一个画板
            Graphics g = Graphics.FromImage(bitmap);

            //设置高质量插值法
            g.InterpolationMode = InterpolationMode.High;

            //设置高质量，低速度呈现平滑程度
            g.SmoothingMode = SmoothingMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(image,
                new Rectangle(0, 0, toWidth, toHeight),
                new Rectangle(x, y, Ow, Oh),
                GraphicsUnit.Pixel);

            try
            {
                bitmap.Save(thumbPath, imageFormat);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (g != null)
                    g.Dispose();
                if (bitmap != null)
                    bitmap.Dispose();
                if (image != null)
                    image.Dispose();
            }

        }


        #region 私有方法

        /// <summary>
        /// 返回上传目录相对路径
        /// </summary>
        /// <param name="fileName">上传文件名</param>
        private string GetUpLoadPath()
        {
            string path = webpath + attachpath + "/"; //站点目录+上传目录
            //按年月日每天一个文件夹
            path += DateTime.Now.ToString("yyyyMMdd");
            return path + "/";
        }

        /// <summary>
        /// 是否为图片文件
        /// </summary>
        /// <param name="_fileExt">文件扩展名，不含“.”</param>
        private bool IsImage(string _fileExt)
        {
            ArrayList al = new ArrayList();
            al.Add("bmp");
            al.Add("jpeg");
            al.Add("jpg");
            al.Add("png");
            if (al.Contains(_fileExt.ToLower()))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 检查是否为合法的上传文件
        /// </summary>
        private bool CheckFileExt(string _fileExt)
        {
            //检查危险文件
            string[] excExt = { "asp", "aspx", "php", "jsp", "htm", "html" };
            for (int i = 0; i < excExt.Length; i++)
            {
                if (excExt[i].ToLower() == _fileExt.ToLower())
                {
                    return false;
                }
            }
            //检查合法文件
            string[] allowExt = attachextension.Split(',');
            for (int i = 0; i < allowExt.Length; i++)
            {
                if (allowExt[i].ToLower() == _fileExt.ToLower())
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 检查文件大小是否合法
        /// </summary>
        /// <param name="_fileExt">文件扩展名，不含“.”</param>
        /// <param name="_fileSize">文件大小(KB)</param>
        private bool CheckFileSize(string _fileExt, int _fileSize)
        {
            //判断是否为图片文件
            if (IsImage(_fileExt))
            {
                if (this.attachimgsize > 0 && _fileSize > this.attachimgsize * 1024)
                {
                    return false;
                }
            }
            else
            {
                if (this.attachfilesize > 0 && _fileSize > this.attachfilesize * 1024)
                {
                    return false;
                }
            }
            return true;
        }

        #endregion
    }
}